package com.yybray.spliterator;

import java.util.Spliterator;
import java.util.function.Consumer;

/**
 * Created by Bray on 2017/6/14.
 */
public class WordCounterSpliterator implements Spliterator<Character> {

    private final String string;
    private int currentCharIndex = 0;
    public WordCounterSpliterator(String string) {
        this.string = string;
    }


    //按顺序一个一个使用Spliterator中的元素，并且如果还有其他元素要遍历就返回true
    @Override
    public boolean tryAdvance(Consumer<? super Character> action) {
        action.accept(string.charAt(currentCharIndex));
        ++currentCharIndex;
        //如果还有字符要处理返回true
        return currentCharIndex < string.length();
    }

    //划分元素
    @Override
    public Spliterator<Character> trySplit() {
        int currentSize = string.length() - currentCharIndex;
        if (currentSize < 10) {
            //返回null表示要解析的String已经足够小，可以顺序处理
            return null;
        }
        //将试探拆分位置设定为要解析的String的中间
        for (int splitPos = currentSize / 2 + currentCharIndex; splitPos < string.length(); splitPos++) {
            //让拆分位置前进直到下一个空格
            if (Character.isWhitespace(string.charAt(splitPos))) {
                //创建一个新的对象来解析拆分好的字符串
                Spliterator<Character> spliterator = new WordCounterSpliterator(string.substring(currentCharIndex, splitPos));
                //将拆分后的索引设置为开始拆分的位置
                currentCharIndex = splitPos;
                return spliterator;
            }
        }
        return null;
    }

    //估计还剩下多少元素要遍历，因为即使不那么确切，能快速算出来是一个值也有助于让拆分均匀一点
    @Override
    public long estimateSize() {
        return string.length() - currentCharIndex;
    }

    @Override
    public int characteristics() {
        /*characteristic方法告诉框架这个Spliterator是ORDERED（顺序就是String
        中各个Character的次序）、SIZED（estimatedSize方法的返回值是精确的）、
        SUBSIZED（trySplit方法创建的其他Spliterator也有确切大小）、NONNULL（String
        中不能有为null 的Character ） 和IMMUTABLE （ 在解析String 时不能再添加
        Character，因为String本身是一个不可变类）的。*/
        return ORDERED + SIZED + SUBSIZED + NONNULL + IMMUTABLE;
    }
}
